package com.xh3140.xwidget.toolbar;

import android.content.Context;
import android.content.res.TypedArray;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

import androidx.appcompat.widget.Toolbar;


public class ToolbarLayout extends ViewGroup {
  private final int mToolbarId;
  private final int mContentId;
  private Toolbar mToolbar;
  private View mContent;

  public ToolbarLayout(Context context) {
    this(context, null);
  }

  public ToolbarLayout(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
  }

  public ToolbarLayout(Context context, AttributeSet attrs, int defStyleAttr) {
    this(context, attrs, defStyleAttr, 0);
  }

  public ToolbarLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);
    final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ToolbarLayout, defStyleAttr, defStyleRes);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
      saveAttributeDataForStyleable(context, R.styleable.ToolbarLayout, attrs, a, defStyleAttr, 0);
    }
    try {
      mToolbarId = a.getResourceId(R.styleable.ToolbarLayout_toolbar, 0);
      if (mToolbarId == 0) {
        throw new IllegalArgumentException("The toolbar attribute is required and must refer to a valid child.");
      }
      mContentId = a.getResourceId(R.styleable.ToolbarLayout_content, 0);
      if (mContentId == 0) {
        throw new IllegalArgumentException("The content attribute is required and must refer to a valid child.");
      }
      if (mToolbarId == mContentId) {
        throw new IllegalArgumentException("The toolbar and content attributes must refer to different children.");
      }
    } finally {
      a.recycle();
    }
  }

  @Override
  protected void onFinishInflate() {
    super.onFinishInflate();
    mToolbar = findViewById(mToolbarId);
    if (mToolbar == null) {
      throw new IllegalArgumentException("The toolbar attribute is must refer to an existing child.");
    }
    mContent = findViewById(mContentId);
    if (mContent == null) {
      throw new IllegalArgumentException("The content attribute is must refer to an existing child.");
    }
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    final int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
    final int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
    if (widthSpecMode == MeasureSpec.UNSPECIFIED || heightSpecMode == MeasureSpec.UNSPECIFIED) {
      throw new RuntimeException("ToolbarLayout cannot have UNSPECIFIED dimensions.");
    }
    final int measuredWidth;
    final int measuredHeight;
    measureChild(mToolbar, widthMeasureSpec, heightMeasureSpec);
    measureChild(mContent, widthMeasureSpec, heightMeasureSpec);
    if (widthSpecMode == MeasureSpec.EXACTLY) {
      measuredWidth = MeasureSpec.getSize(widthMeasureSpec);
    } else {
      measuredWidth = Math.max(mToolbar.getMeasuredWidth(), mContent.getMeasuredWidth());
    }
    if (heightSpecMode == MeasureSpec.EXACTLY) {
      measuredHeight = MeasureSpec.getSize(heightMeasureSpec);
    } else {
      measuredHeight = mToolbar.getMeasuredHeight() + mContent.getMeasuredHeight();
    }
    setMeasuredDimension(measuredWidth, measuredHeight);
  }

  @Override
  protected void onLayout(boolean changed, int l, int t, int r, int b) {
    final int left = getPaddingStart();
    final int top = getPaddingTop();
    final int divider = top + mToolbar.getMeasuredHeight();
    mToolbar.layout(left, top, left + mToolbar.getMeasuredWidth(), divider);
    mContent.layout(left, divider, left + mContent.getMeasuredWidth(), divider + mContent.getMeasuredHeight());
  }

  @Override
  public void addView(View child, int index, LayoutParams params) {
    if (child == null) {
      throw new IllegalArgumentException("add view is null.");
    }
    final int id = child.getId();
    if (id != mToolbarId && id != mContentId) {
      throw new IllegalArgumentException("ToolbarLayout only add toolbar and content refer view.");
    }
    super.addView(child, index, params);
  }
}
